package common;

import java.io.File;
import java.net.InetAddress;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.model.CountryResponse;
import com.maxmind.geoip2.record.City;
import com.maxmind.geoip2.record.Country;
import com.maxmind.geoip2.record.Subdivision;

import dict.CommonDict;
import utils.StringUtil;

public class Ip {

	public final static String NEWYORK = "New York";
	public final static String PENNSYLVANIA = "Pennsylvania";
	public final static String CALIFORNIA = "California";
	public final static String OREGON = "Oregon";
	public final static String VIRGINIA = "Virginia";
	public final static String WASHINGTON = "Washington";

	private static String cityPath = "/usr/local/tomcat7/GeoIP2-City.mmdb";
	private static String countryPath = "/usr/local/tomcat7/GeoIP2-Country.mmdb";
	static {
		if (!"linux".equalsIgnoreCase(System.getProperty("os.name"))) {
			cityPath = "D:\\I-P\\GeoIP2-City.mmdb";
			countryPath = "D:\\I-P\\GeoIP2-Country.mmdb";
		} else {
			cityPath = "/usr/local/tomcat9/GeoIP2-City.mmdb";
			countryPath = "/usr/local/tomcat9/GeoIP2-Country.mmdb";
		}
	}

	public static synchronized String getIp(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	public static synchronized String getCommonIp(String ip) {
		if (StringUtil.isEmpty(ip)) {
			return CommonDict.IP;
		}
		if (ip.equals(CommonDict.LOCALIP)) {
			return CommonDict.IP;
		}
		if (ip.indexOf(",") > 0) {
			return ip.substring(0, ip.indexOf(","));
		}
		return ip;
	}

	public static synchronized String getCountryName(String ip) {
		try {
			DatabaseReader reader = new DatabaseReader.Builder(new File(countryPath)).build();
			CountryResponse response = reader.country(InetAddress.getByName(ip));
			Country country = response.getCountry();
			if (null == country.getName()) {
				return CommonDict.UNKNOWN;
			}
			return country.getName();
		} catch (Exception e) {
			return CommonDict.UNKNOWN;
		}
	}

	public static synchronized String getCountryCode(String ip) {
		try {
			DatabaseReader reader = new DatabaseReader.Builder(new File(countryPath)).build();
			CountryResponse response = reader.country(InetAddress.getByName(ip));
			Country country = response.getCountry();
			if (null == country.getIsoCode()) {
				return CommonDict.UNCODE;
			}
			return country.getIsoCode();
		} catch (Exception e) {
			return CommonDict.UNCODE;
		}
	}

	public static synchronized String getStateName(String ip) {
		try {
			DatabaseReader reader = new DatabaseReader.Builder(new File(cityPath)).build();
			CityResponse response = reader.city(InetAddress.getByName(ip));
			List<Subdivision> list = response.getSubdivisions();
			if (null == list.get(0)) {
				return "unknown";
			}
			return list.get(0).toString();
		} catch (Exception e) {
			return "unknown";
		}
	}

	public static synchronized String getCityName(String ip) {
		try {
			DatabaseReader reader = new DatabaseReader.Builder(new File(cityPath)).build();
			CityResponse response = reader.city(InetAddress.getByName(ip));
			City city = response.getCity();
			if (null == city.getName()) {
				return "unknown";
			}
			return city.getName();
		} catch (Exception e) {
			return "unknown";
		}
	}

	public static synchronized boolean isCountryName(String ip, String name) {
		try {
			DatabaseReader reader = new DatabaseReader.Builder(new File(countryPath)).build();
			CountryResponse response = reader.country(InetAddress.getByName(ip));
			Country country = response.getCountry();
			if (null == country.getName()) {
				return false;
			}
			return name.equalsIgnoreCase(country.getName());
		} catch (Exception e) {
			return false;
		}
	}

	public static synchronized boolean isCountryCode(String ip, String code) {
		try {
			DatabaseReader reader = new DatabaseReader.Builder(new File(countryPath)).build();
			CountryResponse response = reader.country(InetAddress.getByName(ip));
			Country country = response.getCountry();
			if (null == country.getIsoCode()) {
				return false;
			}
			return code.equalsIgnoreCase(country.getIsoCode());
		} catch (Exception e) {
			return false;
		}
	}

	public static synchronized boolean isStateName(String ip, String name) {
		try {
			DatabaseReader reader = new DatabaseReader.Builder(new File(cityPath)).build();
			CityResponse response = reader.city(InetAddress.getByName(ip));
			List<Subdivision> list = response.getSubdivisions();
			if (null == list.get(0)) {
				return false;
			}
			return name.equalsIgnoreCase(list.get(0).toString());
		} catch (Exception e) {
			return false;
		}
	}

	public static synchronized boolean isCityName(String ip, String name) {
		try {
			DatabaseReader reader = new DatabaseReader.Builder(new File(cityPath)).build();
			CityResponse response = reader.city(InetAddress.getByName(ip));
			City city = response.getCity();
			if (null == city.getName()) {
				return false;
			}
			return name.equalsIgnoreCase(city.getName());
		} catch (Exception e) {
			return false;
		}
	}

	public static synchronized boolean isSafeCountry(String code1, String code2) {

		if (code1.equals(CommonDict.UNCODE) || code2.equals(CommonDict.UNCODE) || code1.equalsIgnoreCase(code2)) {
			return true;
		}
		if ((code1.equalsIgnoreCase("PR") && code2.equalsIgnoreCase("US")) || (code1.equalsIgnoreCase("US") && code2.equalsIgnoreCase("PR"))) {
			return true;
		}
		if ((code1.equalsIgnoreCase("DO") && code2.equalsIgnoreCase("US")) || (code1.equalsIgnoreCase("US") && code2.equalsIgnoreCase("DO"))) {
			return true;
		}
		if ((code1.equalsIgnoreCase("RE") && code2.equalsIgnoreCase("FR")) || (code1.equalsIgnoreCase("FR") && code2.equalsIgnoreCase("RE"))) {
			return true;
		}
		if ((code1.equalsIgnoreCase("IE") && code2.equalsIgnoreCase("GB")) || (code1.equalsIgnoreCase("GB") && code2.equalsIgnoreCase("IE"))) {
			return true;
		}
		return false;
	}

}
